package com.goldsign.pay.common.security;

import com.goldsign.pay.common.util.MapKeyComparator;
import com.goldsign.pay.common.string.StringUtil;
import org.apache.commons.codec.binary.Base64;
import org.fusesource.hawtbuf.ByteArrayInputStream;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.X509EncodedKeySpec;
import java.util.Map;
import java.util.TreeMap;

/**
 * 签名工具类
 * @since 1.0.2
 * */
public class SignUtil {

	/**
	 * 从HttpServletRequest得到签名明文, 按参数名字母顺序排列,以&连接的明文字符串,
	 * 去除excludeParam指定的参数.不支持checkbox表单项
	 * @param request
	 * @param excludeParam
	 * @return
	 */
	public static String getSignPlainText(HttpServletRequest request,String excludeParam){
		Map<String,String[]> paramMap = request.getParameterMap();
		if(paramMap == null){
			return null;
		}
		Map<String, String[]> sortMap = new TreeMap<String, String[]>(new MapKeyComparator());
		sortMap.putAll(paramMap);
    	StringBuffer sb = new StringBuffer();
    	String[] values = null;
    	String value = null;
    	for (String key : sortMap.keySet()) {
    		if(key.equalsIgnoreCase(excludeParam)){
    			continue;
    		}
    		values = sortMap.get(key);
    		if(values != null){
    			value = values[0];
    		}
            if (StringUtil.isNotEmpty(value)) {
            	if(sb.length() > 0){
            		sb.append("&" + key).append("=").append(value);
            	}else{
            		sb.append(key).append("=").append(value);
            	}
            }
        }
		return sb.toString();
	}
	/**从Map得到签名明文, 按参数名字母顺序排列,以&连接的明文字符串,去除excludeParam指定的参数.*/
	public static String getSignPlainText(Map<String,String> paramMap,String excludeParam){
		if(paramMap == null || paramMap.isEmpty()){
			return null;
		}
		Map<String, String> sortMap = paramMap;
		if((sortMap instanceof TreeMap) == false){
			sortMap = new TreeMap<String, String>(new MapKeyComparator());
			sortMap.putAll(paramMap);
		}
		
    	StringBuffer sb = new StringBuffer();
    	String value = null;
    	for (String key : sortMap.keySet()) {
    		if(key.equalsIgnoreCase(excludeParam)){
    			continue;
    		}
    		value = sortMap.get(key);
            if (StringUtil.isNotEmpty(value)) {
            	if(sb.length() > 0){
            		sb.append("&" + key).append("=").append(value);
            	}else{
            		sb.append(key).append("=").append(value);
            	}
            }
        }
		return sb.toString();
	}
	
	public static PublicKey getPublicKeyFromCrt(byte[] crtBytes) throws CertificateException{
		PublicKey publicKey = null;
		CertificateFactory cf = null;
    	cf = CertificateFactory.getInstance("X.509");
        X509Certificate encryptCert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(crtBytes));
        publicKey = encryptCert.getPublicKey();
		return publicKey;
	}
	
	
	public static PublicKey getPublicKeyFromPem(byte[] pemBytes) throws Exception{
		PublicKey publicKey = null;
		//去掉pem数据中的注释(首行和末行),去掉换行符,换为回车?
		String base64PublicKeyStr = null;
		ByteArrayInputStream bais = new ByteArrayInputStream(pemBytes);
		BufferedReader br = null;
        try {  
            br= new BufferedReader(new InputStreamReader(bais));  
            String readLine= null;  
            StringBuilder sb= new StringBuilder();  
            while((readLine= br.readLine())!=null){  
                if(readLine.charAt(0)=='-'){  
                    continue;  
                }else{  
                    sb.append(readLine);  
                    sb.append("\r");  
                }  
            }  
            base64PublicKeyStr = sb.toString();
        } finally{
        	if(br!=null){
				try {
					br.close();
				} catch (IOException e) {
				}
        	}
        }
        
        //获取公钥
        byte[] buffer= Base64.decodeBase64(base64PublicKeyStr);
        KeyFactory keyFactory= KeyFactory.getInstance("RSA");  
        X509EncodedKeySpec keySpec= new X509EncodedKeySpec(buffer);  
        publicKey= (PublicKey) keyFactory.generatePublic(keySpec);  
		return publicKey;
	}
	
}
